<template>
	<div class="zfile-file-upload-body">
		<el-dialog v-if="visible" v-model="visible" :destroy-on-close="true"
		           @close="closeDialog"
		           :title="uploadMode === 'file' ? '上传文件' : '上传文件夹'"
		           draggable
		           top="5vh"
		           width="70%">
			<el-upload
				drag
				:http-request="beforeUpload"
				ref="uploadRef"
				:show-file-list="false"
				multiple>
				<el-icon class="el-icon--upload">
					<SvgIcon name="upload-1"></SvgIcon>
				</el-icon>
				<div class="el-upload__text text-gray-400">
          <span v-show="uploadMode === 'file'">
            拖拽文件到这里或<em> 点击上传</em>, 上传至 <em>{{ currentPath }}</em>
          </span>
          <span v-show="uploadMode === 'folder'">
            点击选择文件夹上传, 上传至 <em>{{ currentPath }}</em>
            <br>
            <span class="text-gray-400">（此处不支持拖拽文件夹，只支持点击选择文件夹）</span>
          </span>
				</div>
			</el-upload>
			<div class="mt-5 space-y-2.5">
				<div class="flex flex-row w-full relative rounded-lg" v-for="item in uploadProgressInfoSorted" :key="item.index">

					<div class="mr-2 p-1.5">
						<svg-icon class="text-5xl mt-1 py-1.5 sm:py-1" :name="'file-type-' + common.getFileIconName(item)">
						</svg-icon>
					</div>

					<div class="p-1.5 py-2.5 sm:py-3 w-full flex flex-col justify-between">
						<div class="flex justify-between">
              <div class="flex sm:space-x-5 flex-col sm:flex-row">
                <div class="font-medium text-sm max-w-[80%] line-clamp-1">{{ item.name }}</div>
                <div class="text-gray-400 text-xs leading-5 line-clamp-1 active:line-clamp-none">
                  <span class="mr-4 box animate__animated animate__fadeIn"> {{ common.fileSizeFormat(item.size) }} </span>
                  <span v-if="item.status === 'uploading' && !item.msg" class="text-blue-500 box animate__animated animate__fadeIn">{{ item.speed }} / 秒</span>
                  <span v-if="item.status === 'uploading' && item.msg" class="text-blue-500 box animate__animated animate__fadeIn">{{ item.msg }}</span>
                  <svg-icon v-else-if="item.status === 'finished'" name="check" class="inline text-green-500 box animate__animated animate__fadeIn"/>
                  <span v-else-if="item.status === 'waiting'" class="text-yellow-500 box animate__animated animate__fadeIn">{{ item.msg }}</span>
                  <span v-else-if="item.status === 'error'" class="text-red-500 box animate__animated animate__fadeIn">{{ item.msg }}</span>
                </div>
              </div>
              <div>
                <div v-if="item.status === 'uploading'">
                  <span class="text-gray-500 text-xs mr-2">{{ common.fileSizeFormat(item.loaded) }} / {{ common.fileSizeFormat(item.size) }}</span>
                  <svg-icon @click="cancelUpload(item)" name="tool-close2" class="top-0.5 relative inline text-gray-500 mr-1 text-lg cursor-pointer rounded-full hover:bg-gray-200 box animate__animated animate__fadeIn"/>
                </div>
                <div v-else-if="item.status === 'finished'">
                  <svg-icon @click="removeUploadFileByIndex(item.index)" name="delete" class="inline text-red-400 mr-1 text-base cursor-pointer rounded-full hover:bg-gray-200 box animate__animated animate__fadeIn"/>
                </div>
                <div v-else-if="item.status === 'error'">
                  <svg-icon @click="retryUpload(item)" name="refresh" class="inline text-red-500 mr-1 text-base cursor-pointer rounded-full hover:bg-gray-200 box animate__animated animate__fadeIn"/>
                </div>
                <div v-else-if="item.status === 'waiting'">
                  <svg-icon @click="removeUploadFileByIndex(item.index)" name="delete" class="inline text-red-400 mr-1 text-base cursor-pointer rounded-full hover:bg-gray-200 box animate__animated animate__fadeIn"/>
                </div>
              </div>
            </div>
            <div>
              <el-progress v-if="item.status === 'finished'" :show-text="false" :percentage="item.progress" status="success"></el-progress>
              <el-progress v-else-if="item.status === 'uploading'" :show-text="false" :percentage="item.progress"></el-progress>
              <el-progress v-else-if="item.status === 'error'" :show-text="false" :percentage="100" status="exception"></el-progress>
              <el-progress v-else-if="item.status === 'waiting'" :show-text="false" :percentage="0"></el-progress>
            </div>
					</div>
				</div>
			</div>
		</el-dialog>

		<!-- 文件拖拽提示框-->
		<div ref="dropBoxRef" id="dropBox" class="drop-view" v-if="storageConfigStore.permission.upload" v-show="dropState">
			<div class="drop-sub">
				<span>上传文件至 {{ currentPath }}</span>
			</div>
		</div>

		<div ref="fileUploadAlarmBoxRef" id="fileUploadAlarmBox" class="alarm-view" v-if="!_.isNil(alarmData.fileUpload)">
			<div class="alarm-title">
				<span>文件上传</span>
				<el-icon class="close-icon" @click="closeAlarmDialog">
					<CircleCloseFilled />
				</el-icon>
			</div>
			<div class="alarm-content" v-if="!_.isNil(alarmData.fileUpload) && alarmData.fileUpload.status == 1">
				<div class="alarm-item">
					<el-icon class="successed">
						<SuccessFilled />
					</el-icon>
					<span class="successed-desc">文件上传完毕</span>
				</div>
				<div class="alarm-item">
					<label>文件名：</label>
					<span class="alarm-item-value">{{ alarmData.fileUpload ? alarmData.fileUpload.name : "--" }}</span>
				</div>
				<div class="alarm-item">
					<label>文件大小：</label>
					<span class="alarm-item-value">{{ convertSize(alarmData.fileUpload) }}</span>
				</div>
				<div class="alarm-item">
					<label>上传耗时：</label>
					<span class="alarm-item-value">{{ diffCosts(alarmData.fileUpload) }}</span>
				</div>
				<div class="alarm-item">
					<label>完成时间：</label>
					<span class="alarm-item-value">{{ alarmData.fileUpload ? alarmData.fileUpload.finishTime : "--" }}</span>
				</div>
			</div>
			<div class="alarm-content" v-if="!_.isNil(alarmData.fileUpload) && alarmData.fileUpload.status == 0">
				<div class="alarm-item alarm-failed">
					<el-icon class="failed">
						<Failed />
					</el-icon>
					<span class="failed-desc">文件上传失败</span>
				</div>
				<div class="alarm-item">
					<label>失败时间：</label>
					<span class="alarm-item-value">{{ alarmData.fileUpload.time }}</span>
				</div>
			</div>
		</div>

		<div ref="fileDownloadAlarmBoxRef" id="fileDownloadAlarmBox" class="alarm-view"
			v-if="!_.isNil(alarmData.fileDownload)">
			<div class="alarm-title">
				<span>文件下载</span>
				<el-icon class="close-icon" @click="closeAlarmDialog">
					<CircleCloseFilled />
				</el-icon>
			</div>
			<div class="alarm-content" v-if="!_.isNil(alarmData.fileDownload) && alarmData.fileDownload.status == 1">
				<div class="alarm-item">
					<el-icon class="successed">
						<SuccessFilled />
					</el-icon>
					<span class="successed-desc">文件下载完毕</span>
				</div>
				<div class="alarm-item">
					<label>文件名：</label>
					<span class="alarm-item-value">{{ alarmData.fileDownload ? alarmData.fileDownload.name : "--" }}</span>
				</div>
				<div class="alarm-item">
					<label>下载耗时：</label>
					<span class="alarm-item-value">{{ diffCosts(alarmData.fileDownload) }}</span>
				</div>
				<div class="alarm-item">
					<label>完成时间：</label>
					<span class="alarm-item-value">{{ alarmData.fileDownload ? alarmData.fileDownload.finishTime : "--" }}</span>
				</div>
				<div class="alarm-item">
					<label>保存路径：</label>
					<span class="alarm-item-value">{{ alarmData.fileDownload ? alarmData.fileDownload.savePath : "--" }}</span>
					<el-icon class="copy-link" title="点击复制" @click="copyFilePath">
						<CopyDocument />
					</el-icon>
				</div>
			</div>
			<div class="alarm-content" v-if="!_.isNil(alarmData.fileDownload) && alarmData.fileDownload.status == 0">
				<div class="alarm-item alarm-failed">
					<el-icon class="failed">
						<Failed />
					</el-icon>
					<span class="failed-desc">文件下载失败</span>
				</div>
				<div class="alarm-item">
					<label>失败时间：</label>
					<span class="alarm-item-value">{{ alarmData.fileDownload.time }}</span>
				</div>
			</div>
		</div>

		<div ref="floderUploadAlarmBoxRef" id="floderUploadAlarmBox" class="alarm-view"
			v-if="!_.isNil(alarmData.floderUpload)">
			<div class="alarm-title">
				<span>文件夹上传</span>
				<el-icon class="close-icon" @click="closeAlarmDialog">
					<CircleCloseFilled />
				</el-icon>
			</div>
			<div class="alarm-content" v-if="!_.isNil(alarmData.floderUpload) && alarmData.floderUpload.status == 1">
				<div class="alarm-item">
					<el-icon class="successed">
						<SuccessFilled />
					</el-icon>
					<span class="successed-desc">文件夹下载完毕</span>
				</div>
				<div class="alarm-item">
					<label>上传耗时：</label>
					<span class="alarm-item-value">{{ diffCosts(alarmData.floderUpload) }}</span>
				</div>
				<div class="alarm-item">
					<label>完成时间：</label>
					<span class="alarm-item-value">{{ alarmData.floderUpload ? alarmData.floderUpload.finishTime : "--" }}</span>
				</div>
			</div>
			<div class="alarm-content" v-if="!_.isNil(alarmData.floderUpload) && alarmData.floderUpload.status == 0">
				<div class="alarm-item alarm-failed">
					<el-icon class="failed">
						<Failed />
					</el-icon>
					<span class="failed-desc">文件夹上传失败</span>
				</div>
				<div class="alarm-item">
					<label>失败时间：</label>
					<span class="alarm-item-value">{{ alarmData.floderUpload.time }}</span>
				</div>
			</div>
		</div>

		<div ref="floderDownloadAlarmBoxRef" id="floderDownloadAlarmBox" class="alarm-view"
			v-if="!_.isNil(alarmData.floderDownload)">
			<div class="alarm-title">
				<span>文件夹下载</span>
				<el-icon class="close-icon" @click="closeAlarmDialog">
					<CircleCloseFilled />
				</el-icon>
			</div>
			<div class="alarm-content" v-if="!_.isNil(alarmData.floderDownload) && alarmData.floderDownload.status == 1">
				<div class="alarm-item">
					<el-icon class="successed">
						<SuccessFilled />
					</el-icon>
					<span class="successed-desc">文件夹下载完毕</span>
				</div>
				<div class="alarm-item">
					<label>下载耗时：</label>
					<span class="alarm-item-value">{{ diffCosts(alarmData.floderDownload) }}</span>
				</div>
				<div class="alarm-item">
					<label>完成时间：</label>
					<span class="alarm-item-value">{{ alarmData.floderDownload ? alarmData.floderDownload.finishTime : "--"
						}}</span>
				</div>
				<div class="alarm-item">
					<label>保存路径：</label>
					<span class="alarm-item-value">{{ alarmData.floderDownload ? alarmData.floderDownload.savePath : "--"
						}}</span>
					<el-icon class="copy-link" title="点击复制" @click="copyFilePath">
						<CopyDocument />
					</el-icon>
				</div>
			</div>
			<div class="alarm-content" v-if="!_.isNil(alarmData.floderDownload) && alarmData.floderDownload.status == 0">
				<div class="alarm-item alarm-failed">
					<el-icon class="failed">
						<Failed />
					</el-icon>
					<span class="failed-desc">文件夹下载失败</span>
				</div>
				<div class="alarm-item">
					<label>失败时间：</label>
					<span class="alarm-item-value">{{ alarmData.floderDownload.time }}</span>
				</div>
			</div>
		</div>

	</div>
</template>

<script setup>
import _ from "lodash";
import { CircleCloseFilled, SuccessFilled, Failed, CopyDocument } from '@element-plus/icons-vue';
import common from "~/common";
import {
	STMqttTopic,
	getMonitorMqtt,
} from '~/vendors/business-mqtt';

let router = useRouter();
let route = useRoute();

import useFileSelect from "~/composables/file/useFileSelect";
let { currentPath } = useFileSelect();

import useFileUpload from "~/composables/file/useFileUpload";
const { visible, uploadMode, cancelUpload, beforeUpload, uploadProgressInfoSorted,
	dropState, listenDropFile,
  clearALlFinishedUploadFile, removeUploadFileByIndex, retryUpload} = useFileUpload();

import useStorageConfigStore from "~/stores/storage-config";
let storageConfigStore = useStorageConfigStore();

import useFileDataStore from "~/stores/file-data";
import moment from "moment";
let fileDataStore = useFileDataStore();
let userInfo = window.sessionStorage.getItem("user-info") ? JSON.parse(window.sessionStorage.getItem("user-info")) : {};
let userVo = !_.isEmpty(userInfo) ? userInfo["user_detail"].userVo : {};
let _mqttFileUpload = null;
let _mqttFileDownload = null;
let _mqttFloderUpload = null;
let _mqttFloderDownload = null;
let alarmData = reactive({
	fileUpload: undefined,
	floderUpload: undefined,
	fileDownload: undefined,
	floderDownload: undefined
})
const convertSize = (alarm) => {
	if (!alarm) { return '--'; }
	const { size } = alarm;
	let kb = size / 1024;
	if (kb < 1024) {
		return `${kb.toFixed(2)}KB`;
	}
	if (kb > 1024 && kb < 1024 * 1024) {
		return `${(kb / 1024).toFixed(2)} MB`
	}
	if (kb > 1024 * 1024 && kb < 1024 * 1024 * 1024) {
		return `${(kb / 1024 / 1024).toFixed(2)} TB`
	}
	if (kb > 1024 * 1024 * 1024 && kb < 1024 * 1024 * 1024 * 1024) {
		return `${(kb / 1024 / 1024 / 1024).toFixed(2)} PB`
	}
};
const diffCosts = (alarm) => {
	if (!alarm) { return '--'; }
	const { startTime, finishTime } = alarm;
	let seconds = moment(finishTime).diff(startTime, "seconds");
	if (seconds < 60) {
		return `${seconds} 秒`;
	}
	if (seconds > 60 && seconds < 3600) {
		return `${Math.floor(seconds / 60)}分${seconds % 60} 秒`;
	}
	if (seconds > 3600) {
		return `${Math.floor(seconds / 3600)}小时${Math.floor(seconds % 3600 / 60)}分${Math.floor(seconds % 3600 % 60)} 分`;
	}
};
// 如果有上传完成的文件，关闭对话框时调用 close 方法刷新文件列表
const emit = defineEmits()
const closeDialog = () => {
	let deleteCount = clearALlFinishedUploadFile();
	if (deleteCount > 0) {
		emit('close');
	}
}

const closeAlarmDialog = () => {
	alarmData.fileUpload = undefined;
	alarmData.fileDownload = undefined;
	alarmData.floderUpload = undefined;
	alarmData.floderDownload = undefined;
}

const copyFilePath = () => {
	if (_.isNil(alarmData.fileDownload)) {
		return;
	};
	const { savePath, name } = alarmData.fileDownload;
	const blackboard = document.createElement("input");
	const segments = savePath.split('/');
	segments.pop(); // 移除数组最后一个元素
	let directory = segments.join('/'); // 将剩余的元素重新以'/'连接

	blackboard.setAttribute("value", directory);
	document.body.appendChild(blackboard);
	blackboard.select();
	document.execCommand("copy");
	document.body.removeChild(blackboard);
	ElMessage.success({
		message: `复制成功`,
		duration: 0
	});
}

const startFileUploadMqtt = () => {
	if (!_.isEmpty(userVo)) {
		_mqttFileUpload = getMonitorMqtt(
			`${STMqttTopic.FileUploadAlarm}/${userVo.id}`
		)({
			cb: (rawAlarmList) => {
				let len = rawAlarmList.length - 1;
				let lastAlarm = rawAlarmList[len];
				let src = '';
				// todo
				console.log(lastAlarm)
				alarmData.fileUpload = _.cloneDeep(lastAlarm);
				alarmData.fileDownload = undefined;
				alarmData.floderUpload = undefined;
				alarmData.floderDownload = undefined;
			},
			delay: 500,
			limit: 5,
		});
		_mqttFileUpload.start();
	}
};

const startFileDownloadMqtt = () => {
	if (!_.isEmpty(userVo)) {
		_mqttFileDownload = getMonitorMqtt(
			`${STMqttTopic.FileDownloadAlarm}/${userVo.id}`
		)({
			cb: (rawAlarmList) => {
				let len = rawAlarmList.length - 1;
				let lastAlarm = rawAlarmList[len];
				let src = '';
				// todo
				// todo
				console.log(lastAlarm)
				alarmData.fileDownload = _.cloneDeep(lastAlarm);
				alarmData.fileUpload = undefined;
				alarmData.floderUpload = undefined;
				alarmData.floderDownload = undefined;
			},
			delay: 500,
			limit: 5,
		});
		_mqttFileDownload.start();
	}
};

const startFloderUploadMqtt = () => {
	if (!_.isEmpty(userVo)) {
		_mqttFloderUpload = getMonitorMqtt(
			`${STMqttTopic.FloderUploadAlarm}/${userVo.id}`
		)({
			cb: (rawAlarmList) => {
				let len = rawAlarmList.length - 1;
				let lastAlarm = rawAlarmList[len];
				let src = '';
				// todo
				alarmData.floderUpload = _.cloneDeep(lastAlarm);
				alarmData.floderDownload = undefined;
				alarmData.fileUpload = undefined;
				alarmData.fileDownload = undefined;
			},
			delay: 500,
			limit: 5,
		});
		_mqttFloderUpload.start();
	}
};

const startFloderDownloadMqtt = () => {
	if (!_.isEmpty(userVo)) {
		_mqttFloderDownload = getMonitorMqtt(
			`${STMqttTopic.FloderDowloadAlarm}/${userVo.id}`
		)({
			cb: (rawAlarmList) => {
				let len = rawAlarmList.length - 1;
				let lastAlarm = rawAlarmList[len];
				let src = '';
				// todo
				alarmData.floderDownload = _.cloneDeep(lastAlarm);
				alarmData.floderUpload = undefined;
				alarmData.fileUpload = undefined;
				alarmData.fileDownload = undefined;
			},
			delay: 500,
			limit: 5,
		});
		_mqttFloderDownload.start();
	}
};

// 监听拖拽上传
const dropBoxRef = ref();
onMounted(() => {
	listenDropFile();
})
onMounted(() => {
	listenDropFile();
	startFileUploadMqtt();
	startFileDownloadMqtt();
	startFloderUploadMqtt();
	startFloderDownloadMqtt();
})
onUnmounted(() => {
	if (_mqttFileUpload) {
		_mqttFileUpload.stop();
	};
	if (_mqttFileDownload) {
		_mqttFileDownload.stop();
	};
	if (_mqttFloderUpload) {
		_mqttFloderUpload.stop();
	};
	if (_mqttFloderDownload) {
		_mqttFloderDownload.stop();
	}
})

</script>

<style scoped lang="scss">

.zfile-file-upload-body {
	:deep(.el-dialog__header) {
		text-align: center;
	}

	:deep(.el-dialog__body) {
		max-height: 80vh;
		overflow-y: auto;
	}

  :deep(.el-upload-dragger) {
    @apply border-dashed border-2;
  }

	.drop-view {
		@apply fixed w-full h-full z-10
		bg-opacity-20 bg-black
		left-0 bottom-0
		flex justify-center items-center flex-row;

		.drop-sub {
			@apply flex justify-center items-center h-5/6 w-5/6
			border-dashed border-2 border-gray-400 rounded-2xl
			text-gray-500 font-bold text-2xl;
		}
	}

	.alarm-view {
		position: fixed;
		right: 0px;
		bottom: 0px;
		z-index: 2010;
		width: 430px;
		height: 274px;
		box-sizing: border-box;
		border-radius: 6px;
		background: #fff;
		border: 1px solid #DBDDE2FF;
		box-shadow: 10px 10px 10px 10px rgba(64, 158, 255, 0.8);
		display: flex;
		flex-direction: column;

		.alarm-title {
			position: relative;
			height: 48px;
			font-weight: bolder;
			font-size: 16px;
			background-color: rgb(64, 158, 255, .8);
			color: #fff;
			padding: 16px 20px;
			border-radius: 6px 6px 0 0;
		}

		.alarm-content {
			padding: 4px 20px;
			font-size: 14px;
			height: calc(100% - 48px);
			border: 4px solid rgba(64, 158, 255, 0.8);
			border-radius: 0 0 6px 6px;
		}

		.alarm-item {
			margin: 14px 0;
			display: flex;

			.alarm-item-value {
				display: inline-block;
				width: 280px;
				white-space: nowrap;
				overflow: hidden;
				text-overflow: ellipsis;
			}
		}

		.alarm-failed {
			margin: 10% 0 20% 0;

			.alarm-item-value {
				display: inline-block;
				width: 280px;
				white-space: nowrap;
				overflow: hidden;
				text-overflow: ellipsis;
			}
		}

		.close-icon {
			position: absolute;
			right: 8px;
			color: #fff;
			font-size: 22px;
			cursor: pointer;
		}

		.successed {
			position: relative;
			top: 2px;
			margin-right: 10px;
			color: rgb(89, 185, 92);
			font-size: 22px;
		}

		.failed {
			position: relative;
			top: 2px;
			margin-right: 10px;
			color: #ff0000;
			font-size: 22px;
		}

		.copy-link {
			color: rgb(41, 109, 255);
			font-size: 16px;
			cursor: pointer;
		}

		.successed-desc {
			font-size: 18px;
			color: rgb(89, 185, 92);
		}
		
		.failed-desc {
			font-size: 18px;
			color: #ff0000;
		}
	}
}
</style>